package cc.rengu.igas.bsps.core.service.trans;

import cc.rengu.igas.bsps.common.constant.DubboMethodConstant;
import cc.rengu.igas.bsps.common.enums.RespCodeEnum;
import cc.rengu.igas.bsps.core.realize.PublicDealService;
import cc.rengu.igas.bsps.core.realize.impl.PublicDealServiceImpl;
import cc.rengu.igas.channel.alipay.facade.request.AliAcquireTermInfoRequest;
import cc.rengu.igas.channel.alipay.facade.response.AliAcquireTermInfoResponse;
import cc.rengu.igas.channel.wechat.facade.base.Header;
import cc.rengu.igas.channel.wechat.facade.request.WechatAcquireTermInfoRequest;
import cc.rengu.igas.channel.wechat.facade.response.WechatAcquireTermInfoResponse;
import cc.rengu.igas.channel.wechat.facade.result.Result;
import cc.rengu.igas.share.common.constant.ShareParamConstant;
import cc.rengu.igas.share.common.constant.ShareServiceConstant;
import cc.rengu.igas.share.core.model.MchntInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.oltp.service.base.RadpService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.utility.util.DateUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import com.alibaba.fastjson.JSON;

import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;

/**
 * 异步进行终端信息报备
 *
 * @author yangfan
 * @version 1.0
 * @date 2022/3/21
 */
public class AsynTermInfoReportService extends RadpService {

    @Override
    protected int bizInit(String s) {
        return 0;
    }

    @Override
    protected int bizProcess(String s, int i) {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        try {
            String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
            String termNo = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TERM_NO);
            String mchntNo = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.MCHNT_NO);

            /* Step1：获取商户信息 */
            MchntService mchntService = new MchntServiceImpl();
            MchntInfo mchntInfo = mchntService.getMchntInfo(instId, mchntNo);
            if (null == mchntInfo) {
                rglog.error("获取商户信息失败,mchntNo:<{}>", mchntNo);
                throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
            }

            /* Step2:发往通道报备 */
            /* Step2.1:银联微信-终端信息报备 */
            reportWechat(mchntInfo, termNo);
            /* Step2.2:银联支付宝-终端信息报备 */
            reportAlipay(mchntInfo, termNo);
        } catch (Exception e) {
            rglog.error("异步进行终端信息报备异常！");
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            e.printStackTrace(new PrintWriter(byteArrayOutputStream, true));
            rglog.error("异常信息:<{}>", byteArrayOutputStream.toString());
            return -1;
        }

        return 0;
    }

    @Override
    protected int bizTerminate(String s) {
        return 0;
    }

    /**
     * 通过银联进行微信终端信息报送
     *
     * @param mchntInfo 商户信息
     * @param termNo    终端号
     * @throws Exception 异常
     */
    private void reportWechat(MchntInfo mchntInfo, String termNo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        WechatAcquireTermInfoRequest wechatAcquireTermInfoRequest = new WechatAcquireTermInfoRequest();
        Header wxHeader = new Header();
        wxHeader.setInstId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID));
        wxHeader.setSrcSysId(AppParamConstant.SYS_ID);
        wxHeader.setChanlId(ChannelEnum.BSPS.getChannelType());
        wxHeader.setTransDate(DateUtil.getCurrentDate());
        wxHeader.setTransTime(DateUtil.getCurrentTime());
        wxHeader.setBizType(AppParamConstant.DEFAULT_BIZ_TYPE);
        wxHeader.setVersion(ShareParamConstant.DUBBO_VSERSION);
        wxHeader.setTraceNo(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM));
        wxHeader.setTxnNum("wacquireterminfo");
        wechatAcquireTermInfoRequest.setHeader(wxHeader);

        wechatAcquireTermInfoRequest.setChannelId(ChannelEnum.UPWX.getChannelType());
        wechatAcquireTermInfoRequest.setChannelType(mchntInfo.getWechatChannelType());
        wechatAcquireTermInfoRequest.setThirdMchntNo(mchntInfo.getWechatMchntNo());
        // 本次操作标识: 00-新增 01-修改 02-注销
        wechatAcquireTermInfoRequest.setOperateId("00");
        wechatAcquireTermInfoRequest.setTermNo(termNo);
        wechatAcquireTermInfoRequest.setMchntName(mchntInfo.getMchntName());
        // 设备类型: 11-辅助受理终端
        wechatAcquireTermInfoRequest.setTermType("11");
        // 终端状态: 00-启用 01-注销
        wechatAcquireTermInfoRequest.setTermState("00");
        wechatAcquireTermInfoRequest.setTermAddress(getMerBusiAddress(mchntInfo));
        wechatAcquireTermInfoRequest.setMerRemark(mchntInfo.getMchntNo());
        rglog.debug("微信终端信息采集请求:<{}>", JSON.toJSONString(wechatAcquireTermInfoRequest));

        DubboService dubboService = new DubboServiceImpl();
        Result<WechatAcquireTermInfoResponse> result = (Result<WechatAcquireTermInfoResponse>) dubboService.callDubboService(DubboMethodConstant.WECHAT_MCHNT_SERVICE, ShareServiceConstant.WECHAT_ACQUIRE_TERM_INFO_METHOD, wechatAcquireTermInfoRequest);
        if (null == result || !result.isSuccess() ||
                !RespCodeEnum.TRANS_SUCCESS.getRespCode().equals(result.getResult().getRespCode())) {
            rglog.error("通过银联进行微信终端信息报送失败,商户号:<{}>,终端号:<{}>", mchntInfo.getMchntNo(), termNo);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        } else {
            rglog.info("通过银联进行微信终端信息报送成功,商户号:<{}>,终端号:<{}>", mchntInfo.getMchntNo(), termNo);
        }
    }

    /**
     * 通过银联进行支付宝终端信息报送
     *
     * @param mchntInfo 商户信息
     * @param termNo    终端号
     * @throws Exception 异常
     */
    private void reportAlipay(MchntInfo mchntInfo, String termNo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        AliAcquireTermInfoRequest aliAcquireTermInfoRequest = new AliAcquireTermInfoRequest();
        cc.rengu.igas.channel.alipay.facade.base.Header aliHeader = new cc.rengu.igas.channel.alipay.facade.base.Header();
        aliHeader.setInstId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID));
        aliHeader.setChanlId(ChannelEnum.BSPS.getChannelType());
        aliHeader.setSrcSysId(AppParamConstant.SYS_ID);
        aliHeader.setBizType(AppParamConstant.DEFAULT_BIZ_TYPE);
        aliHeader.setVersion(ShareParamConstant.DUBBO_VSERSION);
        aliHeader.setTxnNum("aacquireterminfo");
        aliHeader.setTraceNo(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM));
        aliHeader.setTransTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_TIME));
        aliHeader.setTransDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_DATE));
        aliAcquireTermInfoRequest.setHeader(aliHeader);

        aliAcquireTermInfoRequest.setChannelId(ChannelEnum.UPAL.getChannelType());
        aliAcquireTermInfoRequest.setChannelType(mchntInfo.getAlipayChannelType());
        aliAcquireTermInfoRequest.setMchntNo(mchntInfo.getMchntNo());
        // 本次操作标识: 00-新增 01-修改 02-注销
        aliAcquireTermInfoRequest.setOperateId("00");
        aliAcquireTermInfoRequest.setTermNo(termNo);
        // 设备类型: 11-辅助受理终端
        aliAcquireTermInfoRequest.setTermType("11");
        // 终端状态: 00-启用 01-注销
        aliAcquireTermInfoRequest.setTermState("00");
        aliAcquireTermInfoRequest.setTermAddress(getMerBusiAddress(mchntInfo));
        aliAcquireTermInfoRequest.setAliMchntNo(mchntInfo.getAlipayMchntNo());
        aliAcquireTermInfoRequest.setMchntName(mchntInfo.getMchntName());
        rglog.debug("支付宝终端信息采集请求:<{}>", JSON.toJSONString(aliAcquireTermInfoRequest));

        DubboService dubboService = new DubboServiceImpl();
        Object object = dubboService.callDubboService(DubboMethodConstant.DUBBO_ALIPAY_MCHNT_SERVICE, ShareServiceConstant.ALI_ACQUIRE_TERM_INFO_METHOD, aliAcquireTermInfoRequest);
        cc.rengu.igas.channel.alipay.facade.result.Result<AliAcquireTermInfoResponse> result = (cc.rengu.igas.channel.alipay.facade.result.Result<AliAcquireTermInfoResponse>) object;
        if (null == result || !result.isSuccess() ||
                !RespCodeEnum.TRANS_SUCCESS.getRespCode().equals(result.getResult().getRespCode())) {
            rglog.error("通过银联进行支付宝终端信息报送失败,商户号:<{}>,终端号:<{}>", mchntInfo.getMchntNo(), termNo);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        } else {
            rglog.info("通过银联进行支付宝终端信息报送成功,商户号:<{}>,终端号:<{}>", mchntInfo.getMchntNo(), termNo);
        }
    }

    /**
     * 获取商户经营地址 终端布放地址: 省-市-区-详细地址
     *
     * @param mchntInfo 商户信息
     * @return 终端布放地址
     * @throws Exception 异常
     */
    private String getMerBusiAddress(MchntInfo mchntInfo) throws Exception {
        PublicDealService publicDealService = new PublicDealServiceImpl();
        String province = publicDealService.getRegionName(mchntInfo.getMchntBizProvince());
        String city = publicDealService.getRegionName(mchntInfo.getMchntBizCity());
        String region = publicDealService.getRegionName(mchntInfo.getMchntBizRegion());
        return String.format("%s-%s-%s-%s", province, city, region, mchntInfo.getMchntBizAddr());
    }
}
